position sticky粘性定位

粘性定位特别适合某些导航栏的交互展示。

1. postion属性

position属性用于指定一个元素在文档中的定位方式。
取值:

  • static:该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。
  • relative:该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。
  • absolute:不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
  • fixed:不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。
  • sticky:盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。position: sticky 对 table 元素的效果与 position: relative 相同。

2. 粘性定位

粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。

须指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。

  • 查看demo(ios或高版本Chrome/Firefox)

其中.m-demo1粘性定位样式如下

1
2
3
position: -webkit-sticky;
position: sticky;
top: 0;

标示”20”(.m-demo1)首先位于19下方,如下图1;在页面滚动到页面窗口顶部时,”20”固定在屏幕顶部,如下图2。
图1
图2

2.1 兼容情况

position sticky

可以看出,兼容情况并非很好,目前主要就ios和高版本Chrome/Firefox兼容较好。在移动端如需兼容android,则需要通过js 来写hack。

如React插件:react-sticky

2.2 动态检查兼容情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @function checkCssSupport
* @param {String} attr 属性名
* @param {String} value 属性值
*/
function checkCssSupport (attr, value) {
let element = document.createElement('div');
if (attr in element.style) {
element.style[attr] = value;
return element.style[attr] === value;
} else return false;
}

checkCssSupport('position', 'sticky');

2.3 不兼容的设备的实现思路

监听页面/容器滚动,设置临界阀值,需要固定时position:fixed,不需要固定的时候position:relative或position:absolute。

3 特点

  • 使用粘性布局的元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
  • 粘性布局的展示效果受其父辈元素影响:父级元素的overflow属性如果不是默认的visible属性,否则sticky元素则相对于该父元素定位(没有粘滞效果),因为改变了滚动容器(即使没有出现滚动条)。因此,如果你的position:sticky无效,看看是不是某一个祖先元素设置了overflow:hidden,移除之即可。

参考: